import pandas as pd
import matplotlib.pyplot as plt

"""
该函数用于处理考试数据，包括读取期中考试和期末考试的Excel文件，对数据进行清洗和转换，计算平均成绩和成绩排名，
并通过合并函数将期中和期末考试数据合并，计算成绩变化和排名变化，将变化分为"进步"和"退步"两类，
并统计进步10名以上的学生人数。最后绘制期末成绩的分布图。

考试.xlsx 电子表格数据例子：

姓名	成绩
林同学	114 
叶同学	118 
陈同学	100 
邓同学	90 

存放在和代码同一目录下便可。

运行程序前，前确保已经有库pandas，若没有请运行 pip install pandas
"""

def handle_exam():
    """
    通过GPT增加代码注释版本
    """
    # 读取期中考试成绩的数据
    df_midterm = pd.read_excel('期中考试.xlsx', sheet_name='成绩')
    # 读取期末考试成绩的数据
    df_final = pd.read_excel('期末考试.xlsx', sheet_name='成绩')

    # 删除期中考试数据中的空值行
    df_midterm = df_midterm.dropna()
    # 删除期末考试数据中的空值行
    df_final = df_final.dropna()

    # 删除期中考试数据中的重复行
    df_midterm = df_midterm.drop_duplicates()
    # 删除期末考试数据中的重复行
    df_final = df_final.drop_duplicates()

    # 将期中考试数据中的成绩转换为浮点型
    df_midterm['成绩'] = df_midterm['成绩'].astype(float)
    # 将期末考试数据中的成绩转换为浮点型
    df_final['成绩'] = df_final['成绩'].astype(float)

    # 计算期中考试的平均成绩
    average_score_midterm = df_midterm['成绩'].mean()
    # 打印期中考试的平均成绩
    print("学生期中平均成绩为: ", average_score_midterm)

    # 计算期末考试的平均成绩
    average_score_final = df_final['成绩'].mean()
    # 打印期末考试的平均成绩
    print("学生期末平均成绩为: ", average_score_final)

    # 对期中考试数据中的成绩进行排名
    df_midterm['成绩排名'] = df_midterm['成绩'].rank(ascending=False)
    # 将期中考试数据中的成绩排名转换为整型
    df_midterm['成绩排名'] = df_midterm['成绩排名'].astype('int32')

    # 对期末考试数据中的成绩进行排名
    df_final['期末成绩排名'] = df_final['成绩'].rank(ascending=False)
    # 将期末考试数据中的成绩排名转换为整型
    df_final['期末成绩排名'] = df_final['期末成绩排名'].astype('int32')

    # 根据姓名将期中考试数据和期末考试数据进行合并
    res = pd.merge(df_final, df_midterm, left_on="姓名", right_on="姓名", how="inner")

    # 对合并后的数据进行重命名
    res.rename(columns={'成绩_x': '期末成绩', '成绩_y': '期中成绩', '成绩排名': '期中成绩排名'}, inplace=True)

    # 计算排名变化
    res["排名变化"] = res["期末成绩排名"] - res["期中成绩排名"]
    # 计算成绩变化
    res["成绩变化"] = res["期末成绩"] - res["期中成绩"]

    # 判断进步或退步
    res['变化'] = res['排名变化'].apply(lambda x: '进步' if x < 0 else '退步')

    # 打印前几行数据
    print(res.head())

    # 打印班级进步10名以上人数
    progressive_student = res[(res['变化'] == "进步") & (res['排名变化'] < -10)]
    print("班级进步10名以上人数：", progressive_student['姓名'].count())

    # 绘制成绩分布图
    score_distribution = res['期末成绩'].value_counts().sort_index()
    plt.bar(score_distribution.index, score_distribution.values)
    plt.xlabel('score')
    plt.ylabel('person')
    plt.title('exam score')
    plt.show()


if __name__ == '__main__':
    handle_exam()
